---@class MoveAction : AbstractLeaf
local MoveAction = ClientFight.CreateClass("MoveAction", ClientFight.AbstractLeaf, ClientFight.IAction)

function MoveAction:ctor()
    ---@type FighterManager
    self.fighterManager = FighterManager
end
---@return EStatus
function MoveAction:update()
    local target = self.fighter.prepareTarget
    if (FighterStateEnum.is(self.fighter, FighterStateEnum.CAN_NOT_MOVE)) then
        SkillRoleMgr.savePathFile("[" .. self.fight.frame .. "][移动]失败" .. self.fighter)
        return EStatus.SUCCESS
    end
    if FighterStateEnum.is(self.fighter, FighterStateEnum.MOVE_TO_POINT) and self.fighter.movePosition ~= nil then
        self:moveToPosition(self.fighter)
        return EStatus.SUCCESS
    end
    if self.fighter.moveTarget ~= target then
        ReportManager.setMoveEndToJsonString(self.fight, self.fighter, self.fighter.moveAction)
        self.fighter.moveAction = ReportManager.moveToJsonString(self.fight, self.fighter)
        --table.insert(self.fight.actions,self.fighter.moveAction)
    end
    self.fighter.moveTarget = target
    if (self.fighter.moveTarget == nil) then
        SkillRoleMgr.savePathFile("[" .. self.fight.frame .. "][移动]" .. self.fighter.fighterId .. "进行移动：目标为空")
        return EStatus.SUCCESS
    end
    ---@type Vector2
    local position = nil
    if (self.fighter.prepareSkill:getAttackShape() ~= nil) then
        position = self:runToPosition2(self.fighter, AttackUtils.getAttackShape(self.fighter, self.fighter.prepareSkill), target)
    else
        position = self:runToPosition(self.fighter, AttackUtils.getAttackRadius(self.fighter, self.fighter.prepareSkill), target)
    end
    self.fighterManager.checkOut(position, self.fighter.shape, Global.FIGHT_INNER_ROUND, false, false)
    EventManager.notifyEventListener(self.fight, FightEventEnum.BEFORE_MOVE, self.fight.fighterId, self.fighter)
    local logPo = position
    SkillRoleMgr.savePathFile("[" .. self.fight.frame .. "][移动]" .. self.fighter.fighterId .. "准备移动：当前坐标" .. getJsonStr(self.fighter.position) .. "，目标坐标：" .. getJsonStr(logPo))

    local distance = DistanceUtil.countDistance(self.fighter.position, position)

    if distance == 0 then
        SkillRoleMgr.savePathFile("[" .. self.fight.frame .. "][移动]" .. self.fighter .. "进行移动：与目标距离为0")
        return EStatus.SUCCESS
    end

    local speed = self.fighterManager.getFighterMoveSpeed(self.fighter)

    local moved = speed * Global.FIGHT_FRAME / 1000.0
    local logSpeed = speed
    if distance <= moved then
        -- 检查是否出界
        self.fighterManager.changePosition(self.fight, self.fighter, moved, position.x, position.y, 0, false, true)
        SkillRoleMgr.savePathFile("[" .. self.fight.frame .. "][移动]" .. self.fighter.fighterId .. "进行速度(" .. logSpeed .. ")移动：移动到" .. getJsonStr(self.fighter.position))

        SkillRoleMgr.savePathFile("[" .. self.fight.frame .. "][MOVE]Fighter " .. self.fighter.fighterId .. " 移动到" .. getJsonStr(self.fighter.position))
        return EStatus.SUCCESS;
    end
    local x = position.x - self.fighter.position.x
    local y = position.y - self.fighter.position.y
    local movedx = x * moved / distance;
    local movedy = y * moved / distance;
    self.fighterManager.changePosition(self.fight, self.fighter, moved, self.fighter.position.x + movedx, self.fighter.position.y + movedy, 0, false, true);

    SkillRoleMgr.savePathFile("[" .. self.fight.frame .. "][移动]" .. self.fighter.fighterId .. "进行速度(" .. logSpeed .. ")移动：移动到" .. getJsonStr(self.fighter.position))
    SkillRoleMgr.savePathFile("[" .. self.fight.frame .. "][MOVE]Fighter " .. self.fighter.fighterId .. " 移动到" .. getJsonStr(self.fighter.position));
    ReportManager.setMoveEndToJsonString(self.fight, self.fighter, self.fighter.moveAction)
    table.insert(self.fight.actions, clone(self.fighter.moveAction))
    FightManager.playActions(self.fighter.moveAction)

    return EStatus.SUCCESS;
end
---计算跑向位置
---@param fighter Fighter
---@param radius number
---@param target Fighter
function MoveAction:runToPosition(fighter, radius, target)
    local distance = DistanceUtil.countDistance(fighter.position, target.position);
    local x = target.position.x
            - (radius - 0.05) * (target.position.x - fighter.position.x) / distance;
    local y = target.position.y
            - (radius - 0.05) * (target.position.y - fighter.position.y) / distance;

    return Vector2(x, y);
end
---计算跑向位置
---@param fighter Fighter
---@param rec1 Rectangle2
---@param target Fighter
function MoveAction:runToPosition2(fighter, rec1, target)
    local x = 0
    local leftOrRight = fighter.position.x < target.position.x and -1 or 1
    if math.abs(fighter.position.x - target.position.x) * 2 > rec1.length + target.shape.length - 0.1 then
        x = target.position.x + leftOrRight * (rec1.length + target.shape.length - 0.1) / 2
    elseif math.abs(fighter.position.x - target.position.x) < Global.MIN_ATTACK_ROUND then
        x = target.position.x + leftOrRight * Global.MIN_ATTACK_ROUND
        if x < Global.FIGHT_INNER_ROUND[1][1] or x > Global.FIGHT_INNER_ROUND[2][1] then
            leftOrRight = -leftOrRight
            x = target.position.x + leftOrRight * Global.MIN_ATTACK_ROUND
        end
    else
        x = fighter.position.x
    end
    local y = 0
    local upOrDown = fighter.position.y < target.position.y and -1 or 1
    -- 横向在攻击距离之外， 需要横向跑动
    if math.abs(fighter.position.y - target.position.y) * 2 > rec1.width + target.shape.width - 0.1 then
        y = target.position.y + upOrDown * (rec1.width + target.shape.width - 0.1) / 2
    else
        y = fighter.position.y
    end
    return Vector2(x, y)
end

---@param fighter Fighter
function MoveAction:moveToPosition(fighter)
    local distance = DistanceUtil.countDistance(fighter.position, fighter.movePosition)
    if distance == 0 then
        return
    end
    local speed = self.fighterManager.getFighterMoveSpeed(fighter);
    local moved = speed * Global.FIGHT_FRAME / 1000.0
    if distance <= moved then
        -- 检查是否出界
        self.fighterManager.changePosition(self.fight, fighter, 0, fighter.movePosition.x, fighter.movePosition.y, 0, false, true);
        return ;
    end
    local x = fighter.movePosition.x - fighter.position.x
    local y = fighter.movePosition.y - fighter.position.y
    local movedx = x * moved / distance
    local movedy = y * moved / distance
    self.fighterManager.changePosition(self.fight, fighter, moved, fighter.position.x + movedx, fighter.position.y + movedy, 0, false, true);
    local logSpeed = speed;
    SkillRoleMgr.savePathFile("[" .. self.fight.frame .. "][移动]移动到指定地点" .. fighter.fighterId .. "进行速度(" .. logSpeed .. ")移动：移动到" .. getJsonStr(fighter.position))
    ReportManager.setMoveEndToJsonString(self.fight, self.fighter, self.fighter.moveAction)
    table.insert(self.fight.actions, clone(self.fighter.moveAction))
    FightManager.playActions(self.fighter.moveAction)
end
